package ar.com.age.distribuidora.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import ar.com.age.distribuidora.dominio.FacturaCompra;
import ar.com.age.distribuidora.dominio.FacturaVenta;
import ar.com.age.distribuidora.dominio.LineaFactura;
import ar.com.age.distribuidora.dominio.LoteDeCompra;
import ar.com.age.distribuidora.service.CompraService;
import ar.com.age.distribuidora.service.InformesService;
import ar.com.age.distribuidora.service.VentaService;
import ar.com.age.distribuidora.service.constantes.IntervaloConstantes;
import ar.com.age.distribuidora.service.nodo.NodoInformes;

public class InformesServiceImpl implements InformesService {

	private VentaService ventaService;
	
	private CompraService compraService;
	
	@Autowired(required = true)
	public void setVentaService(VentaService ventaService) {
		this.ventaService = ventaService;
	}
	
	@Autowired(required = true)
	public void setCompraService(CompraService compraService) {
		this.compraService = compraService;
	}
	
	@SuppressWarnings("deprecation")
	@Override
	public List<NodoInformes> gananciaTotalVentas(int intervalo, String producto, String cliente, String tipoCliente, Date fechaDesde, Date fechaHasta) {

		List<FacturaVenta> ventasInformes = ventaService.getFacturasInformes(producto, cliente, tipoCliente, fechaDesde, fechaHasta);
		List<NodoInformes> nodosInformes = new ArrayList<NodoInformes>();

		switch (intervalo) {
		
		case  IntervaloConstantes.DIARIO: // Diario

			for(FacturaVenta f : ventasInformes) {
				
				NodoInformes nodo = new NodoInformes();
				
				if(producto == "") {

					// Si no se filtra por producto va toda la ganancia de la Factura 
					nodo.setEjeX(Integer.toString(f.getFecha().getDate()) 
									+ "-" + Integer.toString(f.getFecha().getMonth() + 1) 
									+ "-" + Integer.toString(f.getFecha().getYear() + 1900));
					nodo.setEjeY(Double.toString(f.getGanancia()));
				}
				else {
					
					// Si se filtra por producto va la ganancia de la linea
					// Recorro la lista de LineasFactura
					for(LineaFactura l : f.getLineasFactura()) {

						if(l.getLoteDeCompra().getProducto().getCodigo().equals(producto)) {

							nodo.setEjeX(Integer.toString(f.getFecha().getDate()) 
											+ "-" + Integer.toString(f.getFecha().getMonth() + 1) 
											+ "-" + Integer.toString(f.getFecha().getYear() + 1900));
							nodo.setEjeY(Double.toString(l.getGanancia()));
						}
						
					}
				}
				
				nodosInformes.add(nodo);
			}
			
			
			break;
		case IntervaloConstantes.MENSUAL: // Mensual

			for(FacturaVenta f : ventasInformes) {
				
				NodoInformes nodo = new NodoInformes();
				
				if(producto == "") {
					
					// Si no se filtra por producto va toda la ganancia de la Factura 
					nodo.setEjeX(Integer.toString(f.getFecha().getMonth() + 1) + "-" + Integer.toString(f.getFecha().getYear() + 1900));
					nodo.setEjeY(Double.toString(f.getGanancia()));
				}
				else {
					
					// Si se filtra por producto va la ganancia de la linea
					// Recorro la lista de LineasFactura
					for(LineaFactura l : f.getLineasFactura()) {
						if(l.getLoteDeCompra().getProducto().getCodigo().equals(producto)) {
							
							nodo.setEjeX(Integer.toString(f.getFecha().getMonth() + 1) + "-" + Integer.toString(f.getFecha().getYear() + 1900));
							nodo.setEjeY(Double.toString(l.getGanancia()));
						}
						
					}
				}
				
				nodosInformes.add(nodo);
			}


			break;
		case IntervaloConstantes.ANUAL: // Anual":

			for(FacturaVenta f : ventasInformes) {

				NodoInformes nodo = new NodoInformes();

				if(producto == "") {

					// Si no se filtra por producto va toda la ganancia de la Factura 
					nodo.setEjeX(Integer.toString(f.getFecha().getYear() + 1900));
					nodo.setEjeY(Double.toString(f.getGanancia()));
				}
				else {
					
					// Si se filtra por producto va la ganancia de la linea
					// Recorro la lista de LineasFactura
					for(LineaFactura l : f.getLineasFactura()) {
						if(l.getLoteDeCompra().getProducto().getCodigo().equals(producto)) {
							
							nodo.setEjeX(Integer.toString(f.getFecha().getYear() + 1900));
							nodo.setEjeY(Double.toString(l.getGanancia()));
						}
						
					}
				}
				
				nodosInformes.add(nodo);
			}
			
			break;
		
		default: // Todo el rango
			
			break;
		}
		
		return this.agruparSumarNodos(nodosInformes);
	}

	@SuppressWarnings("deprecation")
	@Override
	public List<NodoInformes> cantidadVentas(int intervalo, String producto, String cliente, String tipoCliente, Date fechaDesde, Date fechaHasta) {

		List<FacturaVenta> ventasInformes = ventaService.getFacturasInformes(producto, cliente, tipoCliente, fechaDesde, fechaHasta);
		List<NodoInformes> nodosInformes = new ArrayList<NodoInformes>();

		switch (intervalo) {
		
		case  IntervaloConstantes.DIARIO: // Diario
			
			for(FacturaVenta f : ventasInformes) {
				
				NodoInformes nodo = new NodoInformes();
				
				if(producto == "") {
					
					// Si no se filtra por producto van las cantidades de todas las lineas 
					nodo.setEjeX(Integer.toString(f.getFecha().getDate()) 
									+ "-" + Integer.toString(f.getFecha().getMonth() + 1) 
									+ "-" + Integer.toString(f.getFecha().getYear() + 1900));
					
					Double suma = 0.0;
					for(LineaFactura l : f.getLineasFactura()) {
						suma = suma + l.getCantidad();
					}
					nodo.setEjeY(Double.toString(suma));
				}
				else {
					
					// Si se filtra por producto va la cantidad de la linea
					// Recorro la lista de LineasFactura
					for(LineaFactura l : f.getLineasFactura()) {
						if(l.getLoteDeCompra().getProducto().getCodigo().equals(producto)) {
							
							nodo.setEjeX(Integer.toString(f.getFecha().getDate()) 
											+ "-" + Integer.toString(f.getFecha().getMonth() + 1) 
											+ "-" + Integer.toString(f.getFecha().getYear() + 1900));
							nodo.setEjeY(Double.toString(l.getCantidad()));
						}
					}
				}
				
				nodosInformes.add(nodo);
			}
			
			
			break;
		case IntervaloConstantes.MENSUAL: // Mensual

			for(FacturaVenta f : ventasInformes) {
				
				NodoInformes nodo = new NodoInformes();
				
				if(producto == "") {
					
					// Si no se filtra por producto van las cantidades de todas las lineas 
					nodo.setEjeX(Integer.toString(f.getFecha().getMonth() + 1) + "-" + Integer.toString(f.getFecha().getYear() + 1900));

					Double suma = 0.0;
					for(LineaFactura l : f.getLineasFactura()) {
						suma = suma + l.getCantidad();
					}
					nodo.setEjeY(Double.toString(suma));
				}
				else {
					
					// Si se filtra por producto va la cantidad de la linea
					// Recorro la lista de LineasFactura
					for(LineaFactura l : f.getLineasFactura()) {
						if(l.getLoteDeCompra().getProducto().getCodigo().equals(producto)) {
							
							nodo.setEjeX(Integer.toString(f.getFecha().getMonth() + 1) + "-" + Integer.toString(f.getFecha().getYear() + 1900));
							nodo.setEjeY(Double.toString(l.getCantidad()));
						}
						
					}
				}
				
				nodosInformes.add(nodo);
			}


			break;
		case IntervaloConstantes.ANUAL: // Anual":

			for(FacturaVenta f : ventasInformes) {

				NodoInformes nodo = new NodoInformes();

				if(producto == "") {

					// Si no se filtra por producto van las cantidades de todas las lineas 
					nodo.setEjeX(Integer.toString(f.getFecha().getYear() + 1900));

					Double suma = 0.0;
					for(LineaFactura l : f.getLineasFactura()) {
						suma = suma + l.getCantidad();
					}
					nodo.setEjeY(Double.toString(suma));
				}
				else {
					
					// Si se filtra por producto va la cantidad de la linea
					// Recorro la lista de LineasFactura
					for(LineaFactura l : f.getLineasFactura()) {
						if(l.getLoteDeCompra().getProducto().getCodigo().equals(producto)) {
							
							nodo.setEjeX(Integer.toString(f.getFecha().getYear() + 1900));
							nodo.setEjeY(Double.toString(l.getCantidad()));
						}
						
					}
				}
				
				nodosInformes.add(nodo);
			}
			
			break;
		
		default: // Todo el rango
			
			break;
		}
		
		return this.agruparSumarNodos(nodosInformes);
	}

	@SuppressWarnings("deprecation")
	@Override
	public List<NodoInformes> importeVentas(int intervalo, String producto, String cliente, String tipoCliente, Date fechaDesde, Date fechaHasta) {

		List<FacturaVenta> ventasInformes = ventaService.getFacturasInformes(producto, cliente, tipoCliente, fechaDesde, fechaHasta);
		List<NodoInformes> nodosInformes = new ArrayList<NodoInformes>();

		switch (intervalo) {
		
		case  IntervaloConstantes.DIARIO: // Diario
			
			for(FacturaVenta f : ventasInformes) {
				
				NodoInformes nodo = new NodoInformes();
				
				if(producto == "") {
					
					// Si no se filtra por producto va todo el importe de la Factura 
					nodo.setEjeX(Integer.toString(f.getFecha().getDate()) 
									+ "-" + Integer.toString(f.getFecha().getMonth() + 1) 
									+ "-" + Integer.toString(f.getFecha().getYear() + 1900));
					nodo.setEjeY(Double.toString(f.getTotal()));
				}
				else {
					
					// Si se filtra por producto va el importe de la linea
					// Recorro la lista de LineasFactura
					for(LineaFactura l : f.getLineasFactura()) {
						if(l.getLoteDeCompra().getProducto().getCodigo().equals(producto)) {
							
							nodo.setEjeX(Integer.toString(f.getFecha().getDate()) 
											+ "-" + Integer.toString(f.getFecha().getMonth() + 1) 
											+ "-" + Integer.toString(f.getFecha().getYear() + 1900));
							nodo.setEjeY(Double.toString(l.getCantidad() * l.getPrecio()));
						}
						
					}
				}
				
				nodosInformes.add(nodo);
			}
			
			
			break;
		case IntervaloConstantes.MENSUAL: // Mensual

			for(FacturaVenta f : ventasInformes) {
				
				NodoInformes nodo = new NodoInformes();
				
				if(producto == "") {
					
					nodo.setEjeX(Integer.toString(f.getFecha().getMonth() + 1) + "-" + Integer.toString(f.getFecha().getYear() + 1900));
					nodo.setEjeY(Double.toString(f.getTotal()));
				}
				else {
					
					// Recorro la lista de LineasFactura
					for(LineaFactura l : f.getLineasFactura()) {
						if(l.getLoteDeCompra().getProducto().getCodigo().equals(producto)) {
							
							nodo.setEjeX(Integer.toString(f.getFecha().getMonth() + 1) + "-" + Integer.toString(f.getFecha().getYear() + 1900));
							nodo.setEjeY(Double.toString(l.getCantidad() * l.getPrecio()));
						}
						
					}
				}
				
				nodosInformes.add(nodo);
			}


			break;
		case IntervaloConstantes.ANUAL: // Anual":

			for(FacturaVenta f : ventasInformes) {

				NodoInformes nodo = new NodoInformes();

				if(producto == "") {

					nodo.setEjeX(Integer.toString(f.getFecha().getYear() + 1900));
					nodo.setEjeY(Double.toString(f.getTotal()));
				}
				else {
					
					// Recorro la lista de LineasFactura
					for(LineaFactura l : f.getLineasFactura()) {
						if(l.getLoteDeCompra().getProducto().getCodigo().equals(producto)) {
							
							nodo.setEjeX(Integer.toString(f.getFecha().getYear() + 1900));
							nodo.setEjeY(Double.toString(l.getCantidad() * l.getPrecio()));
						}
						
					}
				}
				
				nodosInformes.add(nodo);
			}
			
			break;
		
		default: // Todo el rango
			
			break;
		}
		
		return this.agruparSumarNodos(nodosInformes);
	}

	@SuppressWarnings("deprecation")
	@Override
	public List<NodoInformes> cantidadCompras(int intervalo, String producto, String proveedor, Date fechaDesde, Date fechaHasta) {

		List<FacturaCompra> comprasInformes = compraService.getFacturasInformes(producto, proveedor, fechaDesde, fechaHasta);
		List<NodoInformes> nodosInformes = new ArrayList<NodoInformes>();

		switch (intervalo) {
		
		case  IntervaloConstantes.DIARIO: // Diario
			
			for(FacturaCompra f : comprasInformes) {
				
				NodoInformes nodo = new NodoInformes();
				
				if(producto == "") {
					
					// Si no se filtra por producto van las cantidades de todas las lineas 
					nodo.setEjeX(Integer.toString(f.getFecha().getDate()) 
									+ "-" + Integer.toString(f.getFecha().getMonth() + 1) 
									+ "-" + Integer.toString(f.getFecha().getYear() + 1900));
					
					Double suma = 0.0;
					for(LoteDeCompra l : f.getLotesDeComra()) {
						suma = suma + l.getCantidadDeCompra();
					}
					nodo.setEjeY(Double.toString(suma));
				}
				else {
					
					// Si se filtra por producto va la cantidad de la linea
					// Recorro la lista de LineasFactura
					for(LoteDeCompra l : f.getLotesDeComra()) {
						if(l.getProducto().getCodigo().equals(producto)) {
							
							nodo.setEjeX(Integer.toString(f.getFecha().getDate()) 
											+ "-" + Integer.toString(f.getFecha().getMonth() + 1) 
											+ "-" + Integer.toString(f.getFecha().getYear() + 1900));
							nodo.setEjeY(Double.toString(l.getCantidadDeCompra()));
						}
					}
				}
				
				nodosInformes.add(nodo);
			}
			
			
			break;
		case IntervaloConstantes.MENSUAL: // Mensual

			for(FacturaCompra f : comprasInformes) {
				
				NodoInformes nodo = new NodoInformes();
				
				if(producto == "") {
					
					// Si no se filtra por producto van las cantidades de todas las lineas 
					nodo.setEjeX(Integer.toString(f.getFecha().getMonth() + 1) + "-" + Integer.toString(f.getFecha().getYear() + 1900));

					Double suma = 0.0;
					for(LoteDeCompra l : f.getLotesDeComra()) {
						suma = suma + l.getCantidadDeCompra();
					}
					nodo.setEjeY(Double.toString(suma));
				}
				else {
					
					// Si se filtra por producto va la cantidad de la linea
					// Recorro la lista de LineasFactura
					for(LoteDeCompra l : f.getLotesDeComra()) {
						if(l.getProducto().getCodigo().equals(producto)) {
							
							nodo.setEjeX(Integer.toString(f.getFecha().getMonth() + 1) + "-" + Integer.toString(f.getFecha().getYear() + 1900));
							nodo.setEjeY(Double.toString(l.getCantidadDeCompra()));
						}
						
					}
				}
				
				nodosInformes.add(nodo);
			}


			break;
		case IntervaloConstantes.ANUAL: // Anual":

			for(FacturaCompra f : comprasInformes) {

				NodoInformes nodo = new NodoInformes();

				if(producto == "") {

					// Si no se filtra por producto van las cantidades de todas las lineas 
					nodo.setEjeX(Integer.toString(f.getFecha().getYear() + 1900));

					Double suma = 0.0;
					for(LoteDeCompra l : f.getLotesDeComra()) {
						suma = suma + l.getCantidadDeCompra();
					}
					nodo.setEjeY(Double.toString(suma));
				}
				else {
					
					// Si se filtra por producto va la cantidad de la linea
					// Recorro la lista de LineasFactura
					for(LoteDeCompra l : f.getLotesDeComra()) {
						if(l.getProducto().getCodigo().equals(producto)) {
							
							nodo.setEjeX(Integer.toString(f.getFecha().getYear() + 1900));
							nodo.setEjeY(Double.toString(l.getCantidadDeCompra()));
						}
						
					}
				}
				
				nodosInformes.add(nodo);
			}
			
			break;
		
		default: // Todo el rango
			
			break;
		}
		
		return this.agruparSumarNodos(nodosInformes);
	}

	@SuppressWarnings("deprecation")
	@Override
	public List<NodoInformes> importeCompras(int intervalo, String producto, String proveedor, Date fechaDesde, Date fechaHasta) {

		List<FacturaCompra> comprasInformes = compraService.getFacturasInformes(producto, proveedor, fechaDesde, fechaHasta);
		List<NodoInformes> nodosInformes = new ArrayList<NodoInformes>();

		switch (intervalo) {
		
		case  IntervaloConstantes.DIARIO: // Diario
			
			for(FacturaCompra f : comprasInformes) {
				
				NodoInformes nodo = new NodoInformes();
				
				if(producto == "") {
					
					nodo.setEjeX(Integer.toString(f.getFecha().getDate()) 
									+ "-" + Integer.toString(f.getFecha().getMonth() + 1) 
									+ "-" + Integer.toString(f.getFecha().getYear() + 1900));
					nodo.setEjeY(Double.toString(f.getTotal()));
				}
				else {
					
					// Recorro la lista de LineasFactura
					for(LoteDeCompra l : f.getLotesDeComra()) {
						if(l.getProducto().getCodigo().equals(producto)) {
							
							nodo.setEjeX(Integer.toString(f.getFecha().getDate()) 
											+ "-" + Integer.toString(f.getFecha().getMonth() + 1) 
											+ "-" + Integer.toString(f.getFecha().getYear() + 1900));
							nodo.setEjeY(Double.toString(l.getCantidadDeCompra() * l.getPrecioDeCompra()));
						}
						
					}
				}
				
				nodosInformes.add(nodo);
			}
			
			
			break;
		case IntervaloConstantes.MENSUAL: // Mensual

			for(FacturaCompra f : comprasInformes) {
				
				NodoInformes nodo = new NodoInformes();
				
				if(producto == "") {
					
					nodo.setEjeX(Integer.toString(f.getFecha().getMonth() + 1) + "-" + Integer.toString(f.getFecha().getYear() + 1900));
					nodo.setEjeY(Double.toString(f.getTotal()));
				}
				else {
					
					// Recorro la lista de LineasFactura
					for(LoteDeCompra l : f.getLotesDeComra()) {
						if(l.getProducto().getCodigo().equals(producto)) {
							
							nodo.setEjeX(Integer.toString(f.getFecha().getMonth() + 1) + "-" + Integer.toString(f.getFecha().getYear() + 1900));
							nodo.setEjeY(Double.toString(l.getCantidadDeCompra() * l.getPrecioDeCompra()));
						}
						
					}
				}
				
				nodosInformes.add(nodo);
			}


			break;
		case IntervaloConstantes.ANUAL: // Anual":

			for(FacturaCompra f : comprasInformes) {

				NodoInformes nodo = new NodoInformes();

				if(producto == "") {

					nodo.setEjeX(Integer.toString(f.getFecha().getYear() + 1900));
					nodo.setEjeY(Double.toString(f.getTotal()));
				}
				else {
					
					// Recorro la lista de LineasFactura
					for(LoteDeCompra l : f.getLotesDeComra()) {
						if(l.getProducto().getCodigo().equals(producto)) {
							
							nodo.setEjeX(Integer.toString(f.getFecha().getYear() + 1900));
							nodo.setEjeY(Double.toString(l.getCantidadDeCompra() * l.getPrecioDeCompra()));
						}
						
					}
				}
				
				nodosInformes.add(nodo);
			}
			
			break;
		
		default: // Todo el rango
			
			break;
		}
		
		return this.agruparSumarNodos(nodosInformes);
	}

	private List<NodoInformes> agruparSumarNodos(List<NodoInformes> lista) {
		
		List<NodoInformes> aux = new ArrayList<NodoInformes>();
		
		int j = 0;
		boolean primera = true;
		for(NodoInformes nodo : lista) {
			
			if(primera) {
				NodoInformes n = new NodoInformes(nodo.getEjeX(), nodo.getEjeY());
				aux.add(n);
				primera = false;
			}
			else {
				
				if(aux.get(j).getEjeX().equals(nodo.getEjeX())) {
					
					aux.get(j).setEjeY(String.valueOf((Double.parseDouble(aux.get(j).getEjeY()) + Double.parseDouble(nodo.getEjeY()))));
				}
				else {
					
					NodoInformes n = new NodoInformes(nodo.getEjeX(), nodo.getEjeY());
					aux.add(n);
					j++;
				}
				
			}
			
		}
		
		return aux;
	}

}
